﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using WinRT;
using WinTime.Contracts.Services;
using WinTime.Core.Contracts.Services;
using WinTime.Core.Enums;
using WinTime.Core.Helpers;
using WinTime.Core.Models;
using WinTime.Data;
using WinTime.Data.Entity;
using WinTime.Helpers;

namespace WinTime.Core.Service;
public class MainService : IMainService
{
    private readonly IAppObserver appObserver;

    private readonly ISettingConfigService settingConfigService;

    public event EventHandler OnUpdateTime;

    public event EventHandler OnStarted;


    public ApplicationDbContext context;

    /// <summary>
    /// 睡眠状态
    /// </summary>
    private SleepStatus sleepStatus;
    /// <summary>
    /// 当前聚焦进程
    /// </summary>
    private string? activeProcess = null;

    /// <summary>
    /// 焦点开始时间
    /// </summary>
    private DateTime activeStartTime = DateTime.Now;

    /// <summary>
    /// 忽略的进程
    /// </summary>
    private readonly string[] DefaultIgnoreProcess = new string[] {
            "WinTime",
            "SearchHost",
            "Taskmgr",
            "ApplicationFrameHost",
            "StartMenuExperienceHost",
            "ShellExperienceHost",
            "OpenWith",
            "Updater",
            "LockApp",
            "dwm",
            "SystemSettingsAdminFlows"
        };
    /// <summary>
    /// 忽略进程缓存列表
    /// </summary>
    private List<string> IgnoreProcessCacheList;

    //  更新应用日期
    private DateTime updadteAppDateTime_ = DateTime.Now.Date;

    /// <summary>
    /// 已经更新过的应用列表
    /// </summary>
    private List<string> updatedAppList = new List<string>();

    public MainService(IAppObserver appObserver, ISettingConfigService settingConfigService)

    {
        IgnoreProcessCacheList = new List<string>();
        this.appObserver = appObserver;
        this.settingConfigService = settingConfigService;

        context = new ApplicationDbContext();

        appObserver.OnAppActive += AppObserver_OnAppActive;

    }


    public void Run()
    {
        Start();
        OnStarted?.Invoke(this, EventArgs.Empty);
        // 重写语言
        Windows.Globalization.ApplicationLanguages.PrimaryLanguageOverride = settingConfigService.SettingConfig.Language;
    }
    public void Start()
    {
        activeStartTime = DateTime.Now;
        activeProcess = null;

        appObserver.Start();
    }
    public void Stop()
    {
        appObserver.Stop();
    }
    public void Exit()
    {
        appObserver?.Stop();
    }


    private void AppObserver_OnAppActive(AppObserverEventArgs args)
    {
        if (sleepStatus == SleepStatus.Sleep)
        {
            return;
        }

        string lastActiveProcess = activeProcess != null ? activeProcess.ToString() : "";

        bool isCheck = IsCheckApp(args.ProcessName, args.Description, args.File);

        Logger.Info($"Active[{isCheck}]:" + args.ProcessName + ",Last:" + lastActiveProcess + ",Time:" + activeStartTime.ToString());

        if (activeProcess != args.ProcessName)
        {
            UpdateTime();
        }

        if (isCheck)
        {
            if (activeProcess == null)
            {
                activeStartTime = DateTime.Now;
            }
            activeProcess = args.ProcessName;
        }
        else
        {
            activeProcess = null;
        }

    }

    private void UpdateTime()
    {
        string app = activeProcess != null ? activeProcess.ToString() : "";

        if (!string.IsNullOrEmpty(app))
        {
            var time = new DateTime(activeStartTime.Ticks);

            //  更新计时
            TimeSpan timeSpan = DateTime.Now - time;
            int seconds = (int)timeSpan.TotalSeconds;

            if (seconds > 3600)
            {
                Logger.Warning($"计时异常。start:{time},process:{app},duration:{seconds},status:{sleepStatus}");
                activeStartTime = DateTime.Now;
                return;
            }

            //  如果是休眠状态要减去5分钟
            if (sleepStatus == SleepStatus.Sleep)
            {
                seconds -= 300;
            }

            if (seconds > 0)
            {
                var currentApp = context.AppModels.Single(x => x.Name == app);
                // 更新总时长
                currentApp.TotalTime += seconds;
                // 记录本次活动时长
                var record = new ActivityRecord();
                record.StartTime = activeStartTime;
                record.StopTime = DateTime.Now;
                record.Time = seconds;
                record.AppModelID = currentApp.ID;
                context.Add(record);
                context.SaveChanges();
            }

            activeStartTime = DateTime.Now;
            OnUpdateTime?.Invoke(this, null);
        }
    }


    /// <summary>
    /// 检查应用是否需要记录数据
    /// </summary>
    /// <param name="processName"></param>
    /// <param name="description"></param>
    /// <param name="file"></param>
    private bool IsCheckApp(string processName, string description, string file)
    {
        if (string.IsNullOrEmpty(file) || string.IsNullOrEmpty(processName) || DefaultIgnoreProcess.Contains(processName) || IgnoreProcessCacheList.Contains(processName))
        {
            return false;
        }

        //  从名称判断
        //if (ConfigIgnoreProcessList.Contains(processName))
        //{
        //    return false;
        //}

        //  正则表达式
        //foreach (string reg in ConfigIgnoreProcessRegxList)
        //{
        //    if (RegexHelper.IsMatch(processName, reg) || RegexHelper.IsMatch(file, reg))
        //    {
        //        IgnoreProcessCacheList.Add(processName);
        //        return false;
        //    }
        //}

        AppModel? app = context.AppModels.SingleOrDefault(x => x.Name == processName);
        if (app == null)
        {
            //  记录应用信息

            //  提取icon
            string iconFile = IconHelper.ExtractFromFile(file, processName, description);
            context.Add(new AppModel()
            {
                Name = processName,
                Description = description,
                File = file,
                CategoryID = 1,
                IconFile = iconFile,
                TotalTime = 0,
            });
        }
        else
        {
            if (updadteAppDateTime_ != DateTime.Now.Date)
            {
                updadteAppDateTime_ = DateTime.Now.Date;
                updatedAppList.Clear();
            }

            if (!updatedAppList.Contains(processName))
            {
                // 更新应用图标
                app.IconFile = IconHelper.ExtractFromFile(file, processName, description);
                // 描述为空时重新赋值
                if (app.Description == "")
                {
                    app.Description = description;
                }
                // 更新应用地址
                if (app.File != file)
                {
                    app.File = file;
                }
                context.Update(app);
                updatedAppList.Add(processName);
            }
        }
        context.SaveChanges();
        return true;
    }
}
